/**
 * \file vector.c
 **/

#include "vector.h"
#include <string.h>
#include "mem.h"

void r_vector_append(RVector* vector, void* data)
{
  assert(vector != NULL);
  vector->size++;
  if (vector->size > vector->alloc_size)
  {
    vector->alloc_size = (vector->alloc_size > 0) ? (2 * vector->alloc_size)
                                                  : 1;
    vector->data = r_mem_realloc(vector->data, vector->alloc_size
                                                 * vector->el_size);
  }
  memcpy(vector->data + (vector->size - 1) * vector->el_size,
         data,
         vector->el_size);
}

void r_vector_clear_lazy(RVector* vector)
{
  vector->size = 0;
}

void* r_vector_get(RVector* vector, uint32_t idx)
{
  assert(vector != NULL);
  return vector->data + idx * vector->el_size;
}

void r_vector_get_into(RVector* vector, uint32_t idx, void* destination)
{
  assert(vector != NULL);
  memcpy(destination, r_vector_get(vector, idx), vector->el_size);
}

void r_vector_init(RVector* vector)
{
  #define R_VECTOR_DEFAULT 2
  r_vector_init_sized(vector, R_VECTOR_DEFAULT);
}

void r_vector_init_sized(RVector* vector, uint32_t size)
{
  vector->size = 0;
  vector->alloc_size = size;
  vector->data = r_mem_malloc(vector->alloc_size * vector->el_size);
}

void r_vector_pop(RVector* vector, void* destination)
{
  assert(vector != NULL);
  assert(vector->size > 0);
  /* TODO: Make pop not be lazy (resize vector). */
  r_vector_get_into(vector, vector->size - 1, destination);
  vector->size--;
}
